/*
 *  This file provided by Facebook is for non-commercial testing and evaluation
 *  purposes only.  Facebook reserves all rights not expressly granted.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

package com.facebook.network.connectionclass.sample.slice;

import com.facebook.network.connectionclass.ConnectionClassManager;
import com.facebook.network.connectionclass.ConnectionQuality;
import com.facebook.network.connectionclass.DeviceBandwidthSampler;
import com.facebook.network.connectionclass.sample.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.window.dialog.ToastDialog;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * MainAbilitySlice
 *
 * @since 2021-02-26
 */
public class MainAbilitySlice extends AbilitySlice {
    private static Logger logger = Logger.getLogger("ConnectionClass-Sample");
    private final static int EVENT_ID_RESULT = 0;
    private final static int EVENT_ID_SUCCESS = 1;
    private final static int EVENT_ID_ERROR = -1;
    private ConnectionClassManager mConnectionClassManager;
    private DeviceBandwidthSampler mDeviceBandwidthSampler;
    private ConnectionChangedListener mListener;
    private Text mTextView;
    private Component mRunningBar;

    private String mURL = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2853553659,1775735885&fm=26&gp=0.jpg";
    private int mTries = 0;
    private ConnectionQuality mConnectionClass = ConnectionQuality.UNKNOWN;
    private EventHandler mHandler;
    private ExecutorService threadExecutor = Executors.newSingleThreadExecutor();

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        mConnectionClassManager = ConnectionClassManager.getInstance();
        mDeviceBandwidthSampler = DeviceBandwidthSampler.getInstance();
        findComponentById(ResourceTable.Id_test_btn).setClickedListener(testButtonClicked);
        mTextView = (Text) findComponentById(ResourceTable.Id_connection_class);
        mTextView.setText(mConnectionClassManager.getCurrentBandwidthQuality().toString());
        mRunningBar = findComponentById(ResourceTable.Id_runningBar);
        mRunningBar.setVisibility(Component.HIDE);
        mListener = new ConnectionChangedListener();
        mHandler = new MyEventHandler(EventRunner.getMainEventRunner());
    }

    @Override
    protected void onActive() {
        super.onActive();
        mConnectionClassManager.register(mListener);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        mConnectionClassManager.remove(mListener);
    }

    /**
     * Listener to update the UI upon connectionclass change.
     */
    private class ConnectionChangedListener
            implements ConnectionClassManager.ConnectionClassStateChangeListener {
        @Override
        public void onBandwidthStateChange(ConnectionQuality bandwidthState) {
            mConnectionClass = bandwidthState;
            mHandler.sendEvent(EVENT_ID_RESULT);
        }
    }

    private final Component.ClickedListener testButtonClicked = new Component.ClickedListener() {
        @Override
        public void onClick(Component v) {
            work();
        }
    };



    private void work() {
        mDeviceBandwidthSampler.startSampling();
        mRunningBar.setVisibility(Component.VISIBLE);

        threadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    // Open a stream to download the image from our URL.
                    URLConnection connection = new URL(mURL).openConnection();
                    connection.setUseCaches(false);
                    connection.connect();
                    InputStream input = connection.getInputStream();
                    try {
                        byte[] buffer = new byte[1024];

                        // Do some busy waiting while the stream is open.
                        while (input.read(buffer) != -1) {
                            logger.log(Level.INFO,"buffer.length = " + buffer.length);

                        }
                    } finally {
                        input.close();
                    }
                    mHandler.sendEvent(EVENT_ID_SUCCESS);
                } catch (IOException e) {
                    logger.log(Level.INFO,"Error while downloading image.");
                    mHandler.sendEvent(EVENT_ID_ERROR);
                }
            }
        });

    }

    private class MyEventHandler extends EventHandler {
        public MyEventHandler(EventRunner runner)
                throws IllegalArgumentException {
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);

            switch (event.eventId) {
                case EVENT_ID_RESULT:
                    mTextView.setText(mConnectionClass.toString());
                    break;
                case EVENT_ID_SUCCESS:
                    mDeviceBandwidthSampler.stopSampling();
                    // Retry for up to 10 times until we find a ConnectionClass.
                    if (mConnectionClass == ConnectionQuality.UNKNOWN && mTries < 15) {
                        mTries++;
                        logger.log(Level.INFO,"mTries=" + mTries);
                        work();
                    }
                    if (!mDeviceBandwidthSampler.isSampling()) {
                        mRunningBar.setVisibility(Component.HIDE);
                    }
                    break;
                case EVENT_ID_ERROR:
                    new ToastDialog(MainAbilitySlice.this).setText("Error while downloading image.").show();
                    mTextView.setText(ConnectionQuality.UNKNOWN.toString());
                    mRunningBar.setVisibility(Component.HIDE);
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.eventId);
            }
        }
    }
}
